package com.auto.survey.activity.monitoring.ctrlmeasure

import android.content.Intent
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.auto.survey.R
import com.auto.survey.activity.bluetooth.BluetoothManagerUtil
import com.auto.survey.activity.monitoring.DoCollectedActivity
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_MEASURE_MODLE
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_OBJECT_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_PROJET_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_STATION_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_INTENT_TASK_ID
import com.auto.survey.activity.monitoring.IntentKey.KEY_MEASURE_MODLE1
import com.auto.survey.activity.monitoring.IntentKey.KEY_MEASURE_MODLE2
import com.auto.survey.activity.monitoring.adapter.CtrlStartMeasureAdapter
import com.auto.survey.activity.monitoring.dao.MonitoringRepository
import com.auto.survey.activity.monitoring.entity.MonitorStauts
import com.auto.survey.activity.monitoring.entity.MonitoringPoint
import com.auto.survey.activity.monitoring.entity.MonitoringPointCtrlObservation
import com.auto.survey.activity.monitoring.entity.relations.MonitoringPointWithCtrlObserv
import com.auto.survey.base.BaseActivity
import com.auto.survey.base.CustomApplication
import com.auto.survey.geocom.CommandContext
import com.auto.survey.geocom.GeoCom
import com.auto.survey.geocom.GeoComCommon
import com.auto.survey.geocom.GeoComHelper
import com.auto.survey.measurecontroller.MeasureConstants.TOTAL_LOOPS
import com.auto.survey.measurecontroller.MeasureProcessListener
import com.auto.survey.measurecontroller.MeasureUICallback
import com.auto.survey.measurecontroller.RefinedMeasureController
import com.auto.survey.measurecontroller.entity.InstrumentStatus
import com.auto.survey.measurecontroller.entity.MeasureConfig
import com.auto.survey.measurecontroller.entity.MeasureTask
import com.auto.survey.measurecontroller.entity.PointMeasureConfig
import com.auto.survey.util.Helper
import com.auto.survey.util.taskqueue.BluetoothTask
import com.auto.survey.util.taskqueue.BluetoothTaskListener
import com.auto.survey.util.taskqueue.BluetoothTaskQueue
import com.auto.survey.util.taskqueue.BluetoothTaskResult
import com.auto.survey.widget.CentreToast
import com.auto.survey.widget.dialog.radiodialog.RadioDialogHelper
import com.auto.survey.widget.dialog.radiodialog.RadioDialogHelper.RadioBean
import com.google.gson.Gson
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.absoluteValue

/**
 * 开始测量
 */
class CtrlStartMeasureActivity : BaseActivity(), View.OnClickListener,MeasureProcessListener, MeasureUICallback {

    private val TAG : String = CtrlStartMeasureActivity::class.java.simpleName
    private var projectId:Int = -1
    private var objectId:Int = -1
    private var stationId:Int = -1
    private var taskId:Int = -1
    private var measurModle: String? = ""
    private val database = MonitoringRepository()
    private val mObservtions = mutableListOf<MonitoringPointWithCtrlObserv>()
    private val mMeasureObservations = mutableListOf<MonitoringPointCtrlObservation>()
    private lateinit var recyclerView: RecyclerView
    private val adapter= CtrlStartMeasureAdapter()
    private lateinit var tv_select: TextView
    private lateinit var tv_log: TextView
    private var mRadioSelectIndex = 0
    private lateinit var monitorStauts: MonitorStauts

    //下面变量自动化测量相关
    private val bluetoothManager by lazy { BluetoothManagerUtil.getInstance(this) }
    private val geoComHelper: GeoComHelper by lazy { GeoComHelper.getInstance(bluetoothManager) }
    private lateinit var measureController: RefinedMeasureController
    // 测量任务相关
    private var currentTask: MeasureTask? = null
    private val viewModel: CtrlStartMeasureViewModle by viewModels()

    private val measureLogList = mutableListOf<String>()


    override fun initView() {
        projectId = intent.getIntExtra(KEY_INTENT_PROJET_ID, -1)
        objectId = intent.getIntExtra(KEY_INTENT_OBJECT_ID, -1)
        stationId = intent.getIntExtra(KEY_INTENT_STATION_ID, -1)
        taskId = intent.getIntExtra(KEY_INTENT_TASK_ID, -1)
        measurModle = intent.getStringExtra(KEY_INTENT_MEASURE_MODLE)

        mTopBar?.visibility = View.VISIBLE
        mTopBar?.setBackgroundResource(R.color.action_bar)

        mComment_title?.visibility = View.VISIBLE
        mComment_title?.setBackgroundResource(R.color.action_bar)
        mComment_title?.setTitle("开始测量  ${measurModle}")

        monitorStauts = MonitorStauts()

        //描述 第几测回  测点名称  盘左盘右 设备状态
        val tv_discrib = findViewById<TextView>(R.id.tv_ctrl_startM_discrib)
        //测距模式
        val tv_modle = findViewById<TextView>(R.id.tv_ctrl_startM_modle)
        //棱镜类型
        val tv_MirrorType = findViewById<TextView>(R.id.tv_ctrl_startM_mirrortype)
        //测量状态
        tv_log = findViewById<TextView>(R.id.tv_ctrl_startM_stauts)
        //测回选择
        tv_select = findViewById<TextView>(R.id.tv_ctrl_startM_selected)
        tv_select.setOnClickListener(this)
        //开始
        findViewById<TextView>(R.id.tv_ctrl_startM).setOnClickListener(this)
        //暂停
        findViewById<TextView>(R.id.tv_ctrl_stopM).setOnClickListener(this)
        //开始(指定测回)
        findViewById<TextView>(R.id.tv_ctrl_startM_num).setOnClickListener(this)
        //返回半自动测量
        findViewById<TextView>(R.id.tv_ctrl_startM_noauto).setOnClickListener(this)
        //测站报告
        findViewById<TextView>(R.id.tv_ctrl_startM_report).setOnClickListener(this)

        settingClickEnable(true)

        recyclerView = findViewById<RecyclerView>(R.id.rv_ctrl_startM)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter


        // 初始化测量控制器
        measureController = RefinedMeasureController(
            geoComHelper = geoComHelper,
            bluetoothManager = bluetoothManager,
            uiCallback = this,
            listener = this
        )

        // 设置蓝牙连接状态监听
        measureController.setBluetoothConnectionListener { isConnected ->
            runOnUiThread {
                var strStat = ""
                if (isConnected) {
                    strStat = "蓝牙已连接，等待开始测量"
                } else {
                    strStat= "蓝牙未连接"
                }
                tv_discrib.text = strStat
            }
        }

        lifecycleScope.launch {

            viewModel.mirrorType.observe(this@CtrlStartMeasureActivity) {
                //棱镜类型
                Log.i(TAG, "viewModel.mirrorType = $it")
                tv_MirrorType.text = it
            }

            viewModel.measureModle.observe(this@CtrlStartMeasureActivity) {
                //测量模式
                Log.i(TAG, "viewModel.measureModle = $it")
                tv_modle.text = it
            }

            viewModel.state.observe(this@CtrlStartMeasureActivity) {
                tv_discrib.text =it.getStauts()
            }
        }
    }

    override fun onResume() {
        super.onResume()
        lifecycleScope.launch {
            mObservtions.clear()
            val data = database.getTaskPointList(taskId)
            //获取即将观测的数据实体
            data?.points?.forEach {
                val bean = database.getMonitoringPointCtrlObservationByPid(it.pointId)
                bean?.let {
                    mObservtions.add(it)
                }
            }

            if (mObservtions.size > 0) {
                mObservtions.expandObservations(TOTAL_LOOPS, 1, 1)
            }

            //获取观测点，用于判断观测点是否已有学习测量的数据，没有则要取初始化测量数据
            var hasEmpty = false
            var tempPoint: MonitoringPoint?=null
            data?.monitoringPoints?.forEach {
                if (it.pointHz == null || it.pointV == null || it.pointSD == null) {
                    hasEmpty = true
                    tempPoint = it
                }
            }

            withContext(Dispatchers.Main) {
                if (hasEmpty) {
                    AlertDialog.Builder(this@CtrlStartMeasureActivity)
                        .setTitle("提示")
                        .setMessage("${tempPoint?.pointName}水平角/竖直角/斜距数据有空值，点击确定进入学习测量")
                        .setPositiveButton("确定") { dialog, _ ->
                            dialog.dismiss()
                            val intent = Intent()
                            intent.putExtra(KEY_INTENT_PROJET_ID, projectId)
                            intent.putExtra(KEY_INTENT_OBJECT_ID, objectId)
                            intent.putExtra(KEY_INTENT_STATION_ID, stationId)
                            intent.setClass(this@CtrlStartMeasureActivity, DoCollectedActivity::class.java)
                            startActivity(intent)
                            finish()
                        }
                        .setNegativeButton("取消") { dialog, _ ->
                            dialog.dismiss()
                            finish()
                        }
                        .show()

                }

            }
        }
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.tv_ctrl_startM_selected->{//选择测回数
                val radios = mutableListOf<RadioBean>()
                for(i in  1 until TOTAL_LOOPS+1 ){
                    radios.add(RadioBean(i, "第 $i 测回"))
                }

                RadioDialogHelper.Builder(this)
                    .setTitle("请选择")
                    .setItems(radios)
                    .setSelectedIndex(mRadioSelectIndex)
                    .setOnItemSelectedListener { position, radioBean ->
                        mRadioSelectIndex = position
                        Log.i(TAG, "选择: ${radioBean.content}, position = $position")
                        tv_select.text = radioBean.content
                    }.build().show()
            }
            R.id.tv_ctrl_startM->{  //开始测量
                settingClickEnable(false)

                val obData = mObservtions.expandObservations(TOTAL_LOOPS, 1, 1)

                val points = mutableListOf<MonitoringPoint>().apply {
                    obData.forEach {
                        add(it.point)
                    }
                }

                // 2. 创建测量配置
                val measureConfig = MeasureConfig(
                    needLeftRight = true,         // 需要测量盘左盘右
                    maxHorizontal2C = 10.0,       // 最大水平角2C互差10秒
                    maxVerticalDiff = 15.0,       // 最大垂直角互差15秒
                    autoRetry = true,             // 允许自动重试
                    retryCount = 2                // 最大重试2次
                )

                // 3. 创建测点个性化配置（可选）
                val pointConfigs = mutableListOf<PointMeasureConfig>().apply {
                    points.forEach {
                        add(PointMeasureConfig(
                            pointCode = it.pointCode,
                            includeLeftFace = true,
                            includeRightFace = true
                        ))
                    }
                }

                Log.i(TAG, "points json = ${Gson().toJson(points)}")

                currentTask = MeasureTask(
                    points = points,
                    config = measureConfig,
                    status = MeasureTask.TaskStatus.IDLE
                )

                // 5. 启动测量任务
                currentTask?.let {
                    measureController.startMeasureTask(it, 1, pointConfigs)
                }
            }
            R.id.tv_ctrl_stopM->{   //停止测量
                settingClickEnable(true)
            }
            R.id.tv_ctrl_startM_num->{//从指定的测回数开始测量
                settingClickEnable(false)
            }
            R.id.tv_ctrl_startM_noauto->{//半自动测量
                CentreToast.instance.showText("暂未实现")
            }
            R.id.tv_ctrl_startM_report->{//生成报告
                CentreToast.instance.showText("暂未实现")
            }
        }
    }

    fun settingClickEnable(enable: Boolean) {
        val btnstart = findViewById<TextView>(R.id.tv_ctrl_startM)
        val btnstop = findViewById<TextView>(R.id.tv_ctrl_stopM)
        val selectNumStart = findViewById<TextView>(R.id.tv_ctrl_startM_num)
        val btnHelfAuto = findViewById<TextView>(R.id.tv_ctrl_startM_noauto)
        val btnReport = findViewById<TextView>(R.id.tv_ctrl_startM_report)

        if (enable) {
            btnstart.isEnabled = true //开始
            btnstop.isEnabled = false //暂停
            selectNumStart.isEnabled = true //开始(指定测回)
            btnHelfAuto.isEnabled = true //返回半自动测量
            btnReport.isEnabled = true//测站报告

            btnstart.isClickable = true //开始
            btnstop.isClickable = false //暂停
            selectNumStart.isClickable = true //开始(指定测回)
            btnHelfAuto.isClickable = true //返回半自动测量
            btnReport.isClickable = true//测站报告


        } else {
            btnstart.isEnabled = false //开始
            btnstop.isEnabled = true //暂停
            selectNumStart.isEnabled = false //开始(指定测回)
            btnHelfAuto.isEnabled = false //返回半自动测量
            btnReport.isEnabled = false//测站报告

            btnstart.isClickable = false //开始
            btnstop.isClickable = true //暂停
            selectNumStart.isClickable = false //开始(指定测回)
            btnHelfAuto.isClickable = false //返回半自动测量
            btnReport.isClickable = false//测站报告
        }
    }

    // 初始化状态更新
    override fun onInitStatusChanged(status: String) {
        Log.i(TAG, "###onInitStatusChanged###   ===> status = $status")
    }
    //蓝牙状态更新
    override fun onBluetoothStateChanged(isBlueToothConnected: Boolean) {
        Log.i(TAG, "###onBluetoothStateChanged###   ===> isBlueToothConnected = $isBlueToothConnected")
    }
    // 测量数据更新（单个测点）
    override fun onMeasureDataUpdated(observation: MonitoringPointCtrlObservation) {
        Log.i(TAG, "###onMeasureDataUpdated###")
    }
    // 测量进度更新（总进度/当前进度）
    override fun onProgressUpdated(current: Int, total: Int) {
        Log.i(TAG, "###onProgressUpdated###   ===> current = $current, total =$total")
    }
    // 测量过程日志（用于列表展示）
    override fun onProcessLogAdded(log: String) {
        measureLogList.add(log)
        runOnUiThread {
            adapter.setItems(measureLogList)
            if (measureLogList.size > 0) {
                recyclerView.scrollToPosition(measureLogList.size - 1);
            }

        }
    }
    // 错误信息提示
    override fun onErrorOccurred(message: String) {
        Log.i(TAG, "###onErrorOccurred###   ===> message = $message")
    }
    // 任务完成通知
    override fun onTaskCompleted(results: List<MonitoringPointCtrlObservation>) {
        Log.i(TAG, "###onTaskCompleted###   ===> results size = ${results.size}")
    }

    //正在测量某个盘位时回调
    override fun onFaceMeasuring(pointName:String, pointCode: String, loopNo: Int, isLeft: Boolean) {
        super.onFaceMeasuring(pointName, pointCode, loopNo, isLeft)
        Log.i(TAG, "###onFaceMeasuring### 正在测量某个盘位时回调  ===> pointCode = $pointCode, loopNo = $loopNo, isLeft = $isLeft")
        runOnUiThread {
            tv_log.text = "正在测量$pointName 测点, 第$loopNo 测回， ${if (isLeft) "盘左" else "盘右"}"
        }

    }

    //完成某个盘位测量时回调
    override fun onFaceMeasured(pointName:String,  pointId: Int, loopNo: Int, index: Int, isLeft: Boolean, observation: MonitoringPointCtrlObservation) {
        super.onFaceMeasured(pointName, pointId, loopNo, index, isLeft, observation)
        Log.i(TAG, "###onFaceMeasured### 完成某个盘位测量时回调  ===> pointName = $pointName, pointId = $pointId, loopNo = $loopNo, index = $index, observation = ${Gson().toJson(observation)}")
        mMeasureObservations.add(observation)
        runOnUiThread {
            tv_log.text = "完成测点${pointName} ${if(index == mObservtions.size-1) "(闭合点)" else ""} ${if(isLeft) "盘左" else "盘右"} 的测量"
            if (index == mObservtions.size - 1 && !isLeft && loopNo == TOTAL_LOOPS) {
                settingClickEnable(true)
            }
        }
    }
    /**
     * 仪器状态更新时回调
     * @param status 更新后的仪器状态
     */
    override fun onInstrumentStatusUpdated(status: InstrumentStatus) {
        Log.i(TAG, "###onInstrumentStatusUpdated###")
        Log.i(TAG, "设备名称 = ${status.equmentName}")
        Log.i(TAG, "倾斜开关状态 = ${status.getInclineSwitch}")
        Log.i(TAG, "倾斜改正状态 = ${status.inClineCorr}")

        Log.i(TAG, "竖轴改正状态 = ${status.standAxisCorr}")
        Log.i(TAG, "视准轴改正状态 = ${status.collimationCorr}")
        Log.i(TAG, "横轴改正状态 = ${status.tiltaxisCorr}")

        Log.i(TAG, "倾斜状态 = ${status.mIncline}")
        Log.i(TAG, "棱镜类型 = ${status.mirrorType}")
        Log.i(TAG, "测量模式 = ${status.measureMode}")

        viewModel.updateMirrorType(status.mirrorType)
        viewModel.updateMeasureModle(status.measureMode)

        val temp = MonitorStauts(equmentName = status.equmentName,
            getInclineSwitch= status.getInclineSwitch,
            inClineCorr = status.inClineCorr,
            standAxisCorr= status.standAxisCorr,
            collimationCorr=status.collimationCorr,
            tiltaxisCorr = status.tiltaxisCorr,
            mIncline = status.mIncline)
        viewModel.updateState(temp)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 释放资源
        measureController.release()
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_ctrl_start_measure
    }


}